/**
 * 
 */
#include "./device_manager.h"
#include "../driver/common/common_modbus.h"
#include "../driver/common/common_modbus_485_port.h"
#include "../bsp/cli_cmd.h"

#ifndef NULL
#define NULL ((void *)0)
#endif

/* 设备支持列表 */
struct {
    unsigned char name[20];
    struct xp_motor *motor;
} xp_motor_support_list[] = {
    0
};

/* 总线属性 */
static struct modbus_485_attr modbus_485_attr[] = {
    {.port = 1, .baudrate = 9600 / 2400, .parity = 2, .timeout = 100 / 10},
    {.port = 2, .baudrate = 9600 / 2400, .parity = 0, .timeout = 100 / 10}};

static struct xp_modbus_bus xp_modbus_485_port[] = {
    {
        .name = "modbus_485_port1",
        .port = 1,
        .sid_set = {0},
        .num_of_dev = 0,
        .private_data = (void *)&modbus_485_attr[0],
    },
    {
        .name = "modbus_485_port2",
        .port = 2,
        .sid_set = {0},
        .num_of_dev = 0,
        .private_data = (void *)&modbus_485_attr[1],
    }
};

static struct xp_modbus_bus *xp_modbus_485_port1 = &xp_modbus_485_port[0];
static struct xp_modbus_bus *xp_modbus_485_port2 = &xp_modbus_485_port[1];

static int xp_modbus_485_port_init()
{
	int ret1 = 0;
	int ret2 = 0;

    /*ret1 = xp_modbus_485_constructor(xp_modbus_485_port1);
    if (ret1 != 0)
    {
        println("xp_modbus_485_port1 init faild.");
    }*/
    
    ret2 = xp_modbus_485_constructor(xp_modbus_485_port2);
    if (ret2 != 0) {
        println("xp_modbus_485_port2 init faild.");
    }

    return (ret1 == 0 && ret2 == 0) ? 0 : (-1);
}

/* 该表用于记录系统中 modbus 设备的相关信息 */
static struct xp_modbus_device xp_modbus_device_list[] = {
    {.sid = 1, .name = "voice_player", .device_attr = NULL},
    {.sid = 2, .name = "led_screen", .device_attr = NULL},

    {},
};

/**
 * @brief 通过 modbus 的设备ID从modbus设备列表中查找对应的 modbus 设备对象
 * @param       sid: modbus 从设备的 id
 * @return      返回 modbus 设备对象的引用地址
 */
struct xp_modbus_device *get_modbus_device_by_sid(unsigned char sid)
{
    for (int i = 0; xp_modbus_device_list[i].sid != 0; i++)
    {
        if (xp_modbus_device_list[i].sid == sid)
            return &xp_modbus_device_list[i];
    }
    return NULL;
}
/**
 * @brief 通过 modbus 的设备名字从modbus设备列表中查找对应的 modbus 设备对象
 * @param       name: modbus 从设备的名字，对应到modbus设备对象的name属性
 * @return      返回 modbus 设备对象的引用地址
 */
struct xp_modbus_device *get_modbus_device_by_name(unsigned char *name)
{
    for (int i = 0; xp_modbus_device_list[i].sid != 0; i++)
    {
        if (0 == strcmp((char *)xp_modbus_device_list[i].name, (char *)name))
            return &xp_modbus_device_list[i];
    }
    return NULL;
}

/**
 * @brief 对系统中用到的设备进行初始化
 * @return      返回 0 表示所有设备均初始化成功
 */
int xp_common_device_init()
{
    int init_state = 0;
    init_state |= xp_modbus_485_port_init();
    
    /*struct xp_modbus_device *dev = get_modbus_device_by_name((unsigned char *)"voice_player");
    init_state |= xp_modbus_device_mount(xp_modbus_485_port1, dev);
    if (dev != NULL) dev->inited = 1;*/
    struct xp_modbus_device *dev = get_modbus_device_by_name((unsigned char *)"led_screen");
    init_state |= xp_modbus_device_mount(xp_modbus_485_port2, dev);
    if (dev != NULL) dev->inited = 1;

    if (init_state != 0)
        return -1;
    return 0;
}
